home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / Real / wfmhcybergfx_r3d.c < prev    next >
C/C++ Source or Header  |  1997-11-28  |  18KB  |  803 lines

  1. #define REVISION "40.3beta"
  2. #define AUTHOR   "Miloslaw Smyk"
  3. #define VERNUM   40
  4. #define REVNUM   3
  5.  
  6. #define PROGNAME    "wfmhcybergfx_r3d.library"
  7.  
  8. #define NAME_RECOG "Real 3D "
  9.  
  10.  
  11. #include <string.h>
  12. #include <exec/types.h>
  13. #include <exec/tasks.h>
  14. #include <exec/execbase.h>
  15. #include <exec/memory.h>
  16. #include <exec/nodes.h>
  17. #include <graphics/modeid.h>
  18. #include <intuition/intuitionbase.h>
  19. #include <intuition/intuition.h>
  20. #include <intuition/screens.h>
  21. #include <clib/exec_protos.h>
  22. #include <pragmas/exec_sysbase_pragmas.h>
  23. #include <clib/intuition_protos.h>
  24. #include <pragmas/intuition_pragmas.h>
  25. #include <cybergraphics/cybergraphics.h>
  26. #include <pragmas/cybergraphics_pragmas.h>
  27. #include <clib/alib_protos.h>
  28. #include <clib/macros.h>
  29. #include <proto/dos.h>
  30. #include <proto/intuition.h>
  31. #include <proto/graphics.h>
  32. #include <proto/asl.h>
  33. #include <proto/cybergraphics.h>
  34. #include <proto/gadtools.h>
  35.  
  36. #include <dos.h>
  37.  
  38. #include "wfmhcybergfx_key.h"
  39. #include "key.h"
  40.  
  41. /* includes for the GUI */
  42. #include "realprefs.h"
  43.  
  44. /* we require 3.0 to work */
  45. long __oslibversion = 39;
  46.  
  47. #define VAR_PATH                    "ENV:wfmhcybergfx_r3d.prefs"
  48. #define VAR_SAVE_PATH         "ENVARC:wfmhcybergfx_r3d.prefs"
  49. #define VAR_LINE_SIZE         80
  50. #define KEYPATH_VAR_SIZE    256
  51. #define KEYPATH_VAR_NAME    "KEYPATH"
  52. #define KEY_NAME                     "wfmhcybergfx_key.library"
  53.  
  54.  
  55. #define TEMPLATE "DITHER/K,NOABOUT/S,POSX/N,POSY/N"
  56.  
  57. #define OPT_DITHER    0
  58. #define OPT_NOABOUT    1
  59. #define OPT_POSX        2
  60. #define OPT_POSY        3
  61. #define OPT_COUNT        4
  62.  
  63. /*
  64. struct R3DHandle
  65. {
  66.     struct Node h_node;
  67.     struct Screen *RenderScr;
  68.     struct Window *wnd;
  69.     UBYTE depth;
  70.     UWORD size_x, size_y;
  71.     struct Task *task;
  72.     SHORT *line;
  73.     int line_width;
  74. };
  75. */
  76.  
  77. struct Library *SysBase;
  78. struct Library *CyberGfxBase;
  79. struct KeyBase *KeyBase;
  80. struct List handle_list;
  81. struct SignalSemaphore sem;
  82. int stop;
  83. int count;
  84. ULONG AboutBox = TRUE;
  85.  
  86. static const char version[] = "\0$VER: " PROGNAME " " REVISION " " __AMIGADATE__ " © 1995-97 " AUTHOR " / World Federation of Mad Hackers";
  87.  
  88. char registration_info[] = "Unfortunately you are not allowed\n\
  89. to use ordered and Floyd-Steinberg\n\
  90. dithering modes in the unregistered\n\
  91. version. Rendering to screens bigger\n\
  92. than 640x512 is also disabled, and you\n\
  93. can only render as much as 50 times.\n\
  94. About box cannot be disabled, either.\n\
  95. \n\
  96. To register, please send $20 or 30DM to\n\
  97. \n\
  98. Miloslaw Smyk\n\
  99. ul. Orawska 22/34\n\
  100. 70-131 Szczecin\n\
  101. POLAND\n\
  102. \n\
  103. Thank you.";
  104.  
  105.  
  106. APTR __asm __saveds R3DInitDspDrv(void);
  107. void __asm __saveds R3DFreeDspDrv(register __a0 APTR handle);
  108. void __asm __saveds R3DSetMode(register __a0 APTR handle);
  109. void __asm __saveds R3DGetSize(register __a0 APTR handle,register __a1 int *x,register __d0 int *y,register __a5 char *data_seg);
  110. void __asm __saveds R3DWriteLine(register __a0 APTR handle,register __a1 int *buffer,register __a2 int len,register __d0 int x,register __d1 int y);
  111. void __asm __saveds R3DReadLine(register __a0 APTR handle,register __a1 int *buffer,register __a2 int len,register __d0 int x,register __d1 int y);
  112. void __asm __saveds R3DClsScr(register __a0 APTR handle,register __a1 ULONG color);
  113. int * __asm __saveds R3DCustomSave(register __a0 APTR handle,register __a1 char *name,register __a2 int x,register __d0 int y,register __d1 int w,register __d2 int h);
  114. int __asm __saveds R3DInitRen(register __a0  struct R3DHandle *handle);
  115. void __asm __saveds R3DEndRen(register __a0  struct R3DHandle *handle);
  116. int __asm __saveds R3DEndRow(register __a0  struct R3DHandle *handle, register __a1 int y);
  117. void __asm __saveds R3DGetAspect(register __a0  struct R3DHandle *handle,register __a1 int *w ,register __d0 int *h);
  118. int __asm __saveds R3DExtF(register __a0  struct R3DHandle *handle);
  119.  
  120.  
  121. int HandleRealPrefsIDCMP( void )
  122. {
  123.     struct IntuiMessage    *m;
  124.     int            (*func)();
  125.     BOOL            running = TRUE;
  126.     ULONG cycle, about;
  127.  
  128.     WaitPort(RealPrefsWnd->UserPort);
  129.     while( m = GT_GetIMsg( RealPrefsWnd->UserPort )) {
  130.  
  131.         CopyMem(( char * )m, ( char * )&RealPrefsMsg, (long)sizeof( struct IntuiMessage ));
  132.  
  133.         GT_ReplyIMsg( m );
  134.  
  135.         switch ( RealPrefsMsg.Class ) {
  136.  
  137.             case    IDCMP_CHANGEWINDOW:
  138.                 RealPrefsLeft   = RealPrefsWnd->LeftEdge;
  139.                 RealPrefsTop    = RealPrefsWnd->TopEdge;
  140.                 break;
  141.  
  142.             case    IDCMP_REFRESHWINDOW:
  143.                 GT_BeginRefresh( RealPrefsWnd );
  144.                 RealPrefsRender();
  145.                 GT_EndRefresh( RealPrefsWnd, TRUE );
  146.                 break;
  147.  
  148.             case    IDCMP_CLOSEWINDOW:
  149.                 running = RealPrefsCloseWindow();
  150.                 break;
  151.  
  152.             case    IDCMP_GADGETUP:
  153.                 func = ( void * )(( struct Gadget * )RealPrefsMsg.IAddress )->UserData;
  154.                 running = func();
  155.                 break;
  156.  
  157.             case IDCMP_VANILLAKEY:
  158.                 switch(RealPrefsMsg.Code)
  159.                 {
  160.                     case 'a':
  161.                     case 'A':
  162.                         GT_GetGadgetAttrs(RealPrefsGadgets[4], RealPrefsWnd, NULL, GTCB_Checked, &about);
  163.                         about = !about;
  164.                         GT_SetGadgetAttrs(RealPrefsGadgets[4], RealPrefsWnd, NULL, GTCB_Checked, about);
  165.                         
  166.                         running = Gadget40Clicked();
  167.                         break;
  168.  
  169.                     case 's':
  170.                     case 'S':
  171.                         running = Gadget10Clicked();
  172.                         break;
  173.  
  174.                     case 'u':
  175.                     case 'U':
  176.                         running = Gadget30Clicked();
  177.                         break;
  178.  
  179.                     case '\x1b':
  180.                     case 'c':
  181.                     case 'C':
  182.                         running = Gadget20Clicked();
  183.                         break;
  184.  
  185.                     case 'd':
  186.                     case 'D':
  187.                         GT_GetGadgetAttrs(RealPrefsGadgets[0], RealPrefsWnd, NULL, GTCY_Active, &cycle);
  188.  
  189.                         if(RealPrefsMsg.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  190.                             cycle = cycle == 0 ? 2 : cycle - 1;
  191.                         else
  192.                             cycle = cycle == 2 ? 0 : cycle + 1;
  193.                             
  194.                         GT_SetGadgetAttrs(RealPrefsGadgets[0], RealPrefsWnd, NULL, GTCY_Active, cycle);
  195.  
  196.                         running = Gadget00Clicked();
  197.                         break;
  198.                 }
  199.  
  200.                 break;
  201.         }
  202.     }
  203.     return( running );
  204. }
  205.  
  206. void msg_req(char *text)
  207. {
  208.     static struct EasyStruct myES =
  209.     {
  210.         sizeof(struct EasyStruct),
  211.         0,
  212.         NULL,
  213.         NULL,
  214.         0
  215.     };
  216.     struct Window *wnd;
  217.     ULONG lock;
  218.  
  219.     myES.es_Title="Information";
  220.     myES.es_TextFormat=text;
  221.     myES.es_GadgetFormat="OK";
  222.  
  223.     lock = LockIBase(0);
  224.     wnd = IntuitionBase->FirstScreen->FirstWindow;
  225.     UnlockIBase(lock);
  226.  
  227.     EasyRequest(wnd, &myES, NULL);
  228. }
  229.  
  230. /* prefs parser done with ReadArgs() */
  231.  
  232. void read_prefs(void)
  233. {
  234.     BPTR fh;
  235.     char var[VAR_LINE_SIZE];
  236.     char *dither_names = "none\1ordered\1fs";
  237.   LONG opts[OPT_COUNT];
  238.   struct RDArgs *rdargs;
  239.     ULONG dither_state;
  240.     int len;
  241.  
  242.     if(fh = Open(VAR_PATH, MODE_OLDFILE))
  243.     {
  244.         if(rdargs = (struct RDArgs *)AllocDosObject(DOS_RDARGS, NULL))
  245.         {
  246.             /* we substract -1 because later we may need to add one more byte at the end of the buffer */
  247.             if(FGets(fh, var, sizeof(var) - 1))
  248.             {
  249.                 // so that ReadArgs() will work if line was terminated by EOF
  250.                 len = strlen(var);
  251.  
  252.                 if(len && var[len - 1] != '\n')
  253.                 {
  254.                     var[len] = '\n';
  255.                     var[++len] = '\0';
  256.                 }
  257.  
  258.                 memset(opts, 0, sizeof(opts));
  259.  
  260.                 rdargs->RDA_Flags |= RDAF_NOPROMPT;
  261.  
  262.                 rdargs->RDA_Source.CS_Buffer = var;
  263.                 rdargs->RDA_Source.CS_Length = len;
  264.  
  265.                 if(rdargs = ReadArgs(TEMPLATE, opts, rdargs))
  266.                 {
  267.                     if(opts[OPT_NOABOUT] && KeyBase)
  268.                         AboutBox = FALSE;
  269.                     
  270.                     if(opts[OPT_POSX])
  271.                         RealPrefsLeft = *(LONG *)opts[OPT_POSX];
  272.  
  273.                     if(opts[OPT_POSY])
  274.                         RealPrefsTop =  *(LONG *)opts[OPT_POSY];
  275.  
  276.                     if(opts[OPT_DITHER])
  277.                     {
  278.                         switch(strstr(dither_names, strlwr((char *)opts[OPT_DITHER])) - dither_names)
  279.                         {
  280.                             case 0:
  281.                                 dither_state = DT_NONE;
  282.                                 break;
  283.                             case 5:
  284.                                 dither_state = DT_ORDERED;
  285.                                 break;
  286.                             case 13:
  287.                                 dither_state = DT_FS;
  288.                                 break;
  289.                             default:
  290.                                 dither_state = DT_NONE;
  291.                                 msg_req("Error:\nUnknown dither type in prefs file.");
  292.                                 break;
  293.                         }
  294.  
  295.                         if(KeyBase)
  296.                             SetDitherType(dither_state);
  297.                     }
  298.                     FreeArgs(rdargs);
  299.                 }
  300.                 else
  301.                     msg_req("Error:\nUnable to parse prefs file.");
  302.             }
  303.             FreeDosObject(DOS_RDARGS, rdargs);
  304.         }
  305.  
  306.         Close(fh);
  307.     }
  308. }
  309.  
  310. int check_task(struct Task *task)
  311. {
  312.     struct Task *node;
  313.     int ret_val = FALSE;
  314.  
  315.     if(FindTask(NULL) == task)
  316.         return(TRUE);
  317.  
  318.     Disable();
  319.  
  320.     for(node = (struct Task *)((struct ExecBase *)SysBase)->TaskReady.lh_Head; node->tc_Node.ln_Succ; node = (struct Task *)node->tc_Node.ln_Succ)
  321.         if(node == task)
  322.             ret_val = TRUE;
  323.  
  324.     if(!ret_val)
  325.         for(node = (struct Task *)((struct ExecBase *)SysBase)->TaskWait.lh_Head; node->tc_Node.ln_Succ; node = (struct Task *)node->tc_Node.ln_Succ)
  326.             if(node == task)
  327.                 ret_val = TRUE;
  328.  
  329.     Enable();
  330.  
  331.     return(ret_val);
  332. }
  333.  
  334. struct R3DHandle *get_handle(struct R3DHandle *first, struct Task *task)
  335. {
  336.     struct R3DHandle *node, *temp, *ret_val = NULL;
  337.  
  338.     ObtainSemaphore(&sem);
  339.  
  340.     node = first;
  341.  
  342.     while(node->h_node.ln_Succ)
  343.     {
  344.         if(node->task && !check_task(node->task))
  345.         {
  346.             /* remove task info from R3DHandles list */
  347.  
  348.             temp = (struct R3DHandle *)node->h_node.ln_Succ;
  349.             Remove((struct Node *)node);
  350.  
  351.             if(node->line)
  352.                 FreeVec(node->line);
  353.  
  354.             FreeVec(node);
  355.  
  356.             node = temp;
  357.         }
  358.         else
  359.             node = (struct R3DHandle *)node->h_node.ln_Succ;
  360.     }
  361.  
  362.  
  363.     for(node = first; node->h_node.ln_Succ; node = (struct R3DHandle *)node->h_node.ln_Succ)
  364.         if(node->task && node->task == task)
  365.         {
  366.             ret_val = node;
  367.             break;
  368.         }
  369.  
  370.  
  371.     if(!ret_val && (node = AllocVec(sizeof(struct R3DHandle), MEMF_CLEAR | MEMF_ANY)))
  372.     {
  373.         node->task = task;
  374.  
  375.         AddTail(&handle_list, (struct Node *)node);
  376.         ret_val = node;
  377.     }
  378.  
  379.     ReleaseSemaphore(&sem);
  380.     return(ret_val);
  381. }
  382.  
  383.  
  384. void __asm __saveds putch_proc(register __d0 char c, register __a3 char **buf)
  385. {
  386.     **buf = c;
  387.     (*buf)++;
  388. }
  389.  
  390. APTR __asm __saveds R3DInitDspDrv()
  391. {
  392.     struct R3DHandle *R3DH;
  393.     char buffer[400], *buf = buffer;
  394.     struct UserInfo *user;
  395.  
  396.     if(KeyBase)
  397.         user = GetUserInfo();
  398.  
  399.     if(R3DH = AllocVec(sizeof(struct R3DHandle), MEMF_CLEAR | MEMF_PUBLIC))
  400.     {
  401.         ObtainSemaphore(&sem);
  402.  
  403.         AddTail(&handle_list, (struct Node *)R3DH);
  404.  
  405.         ReleaseSemaphore(&sem);
  406.  
  407.         read_prefs();
  408.  
  409.         if(KeyBase)
  410.             RawDoFmt("wfmhcybergfx_r3d.library\n\
  411. by Miloslaw Smyk\n\n\
  412. Version " REVISION ", compiled on " __DATE__ "\n\n\
  413. This copy (#%04ld) is registered to:\n\n\
  414. %s\n\
  415. %s\n\
  416. %s\n\
  417. %s\n\
  418. \nPlease do not redistribute.", user, putch_proc, &buf);
  419.         else
  420.             RawDoFmt("wfmhcybergfx_r3d.library\n\
  421. by Miloslaw Smyk\n\n\
  422. Version " REVISION ", compiled on " __DATE__ "\n\n\
  423. Unregistered version.", NULL, putch_proc, &buf);
  424.  
  425.         if(AboutBox)
  426.             msg_req(buffer);
  427.  
  428.         if(KeyBase)
  429.             InitDithering();
  430.  
  431.         return((APTR)R3DH);
  432.     }
  433. }
  434.  
  435.  
  436. void __asm __saveds R3DFreeDspDrv(register __a0 struct R3DHandle *handle)
  437. {
  438.     struct R3DHandle *node, *temp;
  439.  
  440.     if(handle)
  441.     {
  442.         ObtainSemaphore(&sem);
  443.  
  444.         node = handle;
  445.  
  446.         while(node->h_node.ln_Succ)
  447.         {
  448.             /* remove task info from R3DHandles list */
  449.  
  450.             temp = (struct R3DHandle *)node->h_node.ln_Succ;
  451.             Remove((struct Node *)node);
  452.  
  453.             if(node->line)
  454.                 FreeVec(node->line);
  455.  
  456.             FreeVec(node);
  457.  
  458.             node = temp;
  459.         }
  460.  
  461.         ReleaseSemaphore(&sem);
  462.     }
  463. }
  464.  
  465.  
  466. /* routine when gadget "_Dithering" is clicked. */
  467.  
  468. int Gadget00Clicked( void )
  469. {
  470.     ULONG cycle;
  471.  
  472.     GT_GetGadgetAttrs(RealPrefsGadgets[0], RealPrefsWnd, NULL, GTCY_Active, &cycle);
  473.  
  474.     if(cycle != DT_NONE && !KeyBase)
  475.     {
  476.         msg_req(registration_info);
  477.         GT_SetGadgetAttrs(RealPrefsGadgets[0], RealPrefsWnd, NULL, GTCY_Active, DT_NONE);
  478.     }
  479.  
  480.     return(TRUE);
  481. }
  482.  
  483.  
  484. int save_prefs(char *name)
  485. {
  486.     BPTR fh;
  487.     char *dither_name[3] = { "FS", "ORDERED", "NONE" };
  488.     int    err;
  489.     char buffer[200], *buf;
  490.  
  491.     buf = buffer;
  492.  
  493.     err = TRUE;
  494.  
  495.     if(fh = Open(name, MODE_NEWFILE))
  496.     {
  497.         if(-1 != FPrintf((LONG)fh, "DITHER=%s %s%ld %ld\n", dither_name[KeyBase ? KeyBase->dither_type : DT_NONE],
  498.                             (AboutBox ? "" : "NOABOUT "), RealPrefsLeft,    RealPrefsTop))
  499.             err = FALSE;
  500.  
  501.         Close(fh);
  502.     }
  503.  
  504.     if(err)
  505.     {
  506.         RawDoFmt("Error:\nUnable to save prefs file as\n%s", &name, putch_proc, &buf);
  507.         msg_req(buffer);
  508.         return(TRUE);
  509.     }
  510.  
  511.     return(FALSE);
  512. }
  513.  
  514. /* routine when gadget "_Save" is clicked. */
  515. int Gadget10Clicked( void )
  516. {
  517.     ULONG cycle;
  518.  
  519.     GT_GetGadgetAttrs(RealPrefsGadgets[0], RealPrefsWnd, NULL, GTCY_Active, &cycle);
  520.     GT_GetGadgetAttrs(RealPrefsGadgets[4], RealPrefsWnd, NULL, GTCB_Checked, &AboutBox);
  521.  
  522.     if(KeyBase)
  523.         SetDitherType(cycle);
  524.  
  525.     save_prefs(VAR_PATH);
  526.  
  527.     /* do not close window if prefs can't be saved to disk */
  528.     return(save_prefs(VAR_SAVE_PATH));
  529. }
  530.  
  531. /* routine when gadget "_Cancel" is clicked. */
  532. int Gadget20Clicked( void )
  533. {
  534.     return(FALSE);
  535. }
  536.  
  537. /* routine when gadget "_Use" is clicked. */
  538. int Gadget30Clicked( void )
  539. {
  540.     ULONG cycle;
  541.  
  542.     GT_GetGadgetAttrs(RealPrefsGadgets[0], RealPrefsWnd, NULL, GTCY_Active, &cycle);
  543.     GT_GetGadgetAttrs(RealPrefsGadgets[4], RealPrefsWnd, NULL, GTCB_Checked, &AboutBox);
  544.  
  545.     if(KeyBase)
  546.         SetDitherType(cycle);
  547.  
  548.     save_prefs(VAR_PATH);
  549.  
  550.     return(FALSE);
  551. }
  552.  
  553. /* checkbox "About" changed state */
  554.  
  555. int Gadget40Clicked( void )
  556. {
  557.     ULONG about;
  558.  
  559.     GT_GetGadgetAttrs(RealPrefsGadgets[4], RealPrefsWnd, NULL, GTCB_Checked, &about);
  560.  
  561.     if(about == FALSE && !KeyBase)
  562.     {
  563.         msg_req(registration_info);
  564.         GT_SetGadgetAttrs(RealPrefsGadgets[4], RealPrefsWnd, NULL, GTCB_Checked, TRUE);
  565.     }
  566.  
  567.     return(TRUE);
  568. }
  569.  
  570. int RealPrefsCloseWindow( void )
  571. {
  572.     /* routine for "IDCMP_CLOSEWINDOW". */
  573.     return(FALSE);
  574. }
  575.  
  576. void __asm __saveds R3DSetMode(register __a0 struct R3DHandle *handle)
  577. {
  578.     ULONG lock;
  579.     struct Screen *scr;
  580.  
  581.     lock = LockIBase(0);
  582.     scr = IntuitionBase->FirstScreen;
  583.     UnlockIBase(lock);
  584.  
  585.     if(!(scr->Flags & PUBLICSCREEN))
  586.         scr = NULL;
  587.  
  588.     if(!SetupScreen(scr))
  589.     {
  590.         if(!OpenRealPrefsWindow())
  591.         {
  592.             while(HandleRealPrefsIDCMP());
  593.  
  594.             CloseRealPrefsWindow();
  595.         }
  596.         CloseDownScreen();
  597.     }
  598. }
  599.  
  600. void __asm __saveds R3DGetSize(register __a0 struct R3DHandle *handle,register __a1 int *x,register __d0 int *y, register __a5 char *data_seg)
  601. {
  602.     ULONG lock;
  603.     struct Window *wnd;
  604.     struct Task *this;
  605.     struct Task *task = NULL;
  606.  
  607.     int *stc = (int *)getreg(REG_A7);
  608.  
  609.     /* let's get the address of currently selected window */
  610.     lock = LockIBase(0);
  611.     wnd = IntuitionBase->ActiveWindow;
  612.     UnlockIBase(lock);
  613.  
  614.     /* If user just toggled "rendering output" gadget in Settings window to "External",
  615.     ** we skip further processing. */
  616.  
  617.     if(strncmp(wnd->Title, NAME_RECOG, sizeof(NAME_RECOG) - 1))
  618.     {
  619.         if(strncmp(((struct Task *)wnd->UserPort->mp_SigTask)->tc_Node.ln_Name, "View", 4))
  620.         {
  621.             ULONG lock;
  622.             struct Screen *scr;
  623.             struct Window *w;
  624.  
  625.             lock = LockIBase(0);
  626.             scr = IntuitionBase->FirstScreen;
  627.  
  628.             for(w = scr->FirstWindow; w; w = w->NextWindow)
  629.                 if(!strncmp(((struct Task *)w->UserPort->mp_SigTask)->tc_Node.ln_Name, "View", 4))
  630.                 {
  631.                     wnd = w;
  632.                     UnlockIBase(lock);
  633.                     goto out;
  634.                 }
  635.  
  636.             UnlockIBase(lock);
  637.             return;
  638.         }
  639.  
  640. out:
  641.         /* if we are called from a process (what in fact means Real's main thread), we take
  642.         ** a different route */
  643.  
  644.         this = FindTask(NULL);
  645.  
  646.         if(this->tc_Node.ln_Type == NT_PROCESS)
  647.         {
  648.             if(stc[34])
  649.             {
  650.                 task = ((struct Message*)stc[34])->mn_ReplyPort->mp_SigTask;
  651.                 handle = get_handle(handle, task);
  652.             }
  653.  
  654.             handle->wnd = wnd;
  655.         }
  656.         else
  657.         {
  658.             handle = get_handle(handle, this);
  659.  
  660.             /* set DrawTask's R3DHandle address */
  661.             *(struct R3DHandle **)&data_seg[0x2e] = handle;
  662.  
  663.             count++;
  664.             if(handle->line)
  665.                 memset(handle->line, 0, sizeof(SHORT) * (handle->line_width + 2) * 3);
  666.         }
  667.  
  668.         handle->size_x = *x = handle->wnd->Width - handle->wnd->BorderLeft - handle->wnd->BorderRight;
  669.         handle->size_y = *y = handle->wnd->Height - handle->wnd->BorderTop - handle->wnd->BorderBottom;
  670.  
  671.         handle->depth = GetCyberIDAttr(CYBRIDATTR_DEPTH, GetVPModeID(&handle->wnd->WScreen->ViewPort));
  672.        if(task && handle->depth >= 15)
  673.             *(int *)&data_seg[0x26c] = 0;    /* force Real to take new window's size under consideration :) */
  674.     }
  675.     else
  676.         *x = *y = 1;
  677. }
  678.  
  679. void __asm __saveds R3DWriteLine(register __a0 struct R3DHandle *handle,register __a1 int *buffer,register __a2 int len,register __d0 int x, register __d1 int y)
  680. {
  681.     int *a = 0;
  682.  
  683.     if(!handle)
  684.         *a = 0xeeee;
  685.  
  686.     if(handle->wnd)
  687.     {
  688.         if(handle->depth < 15)
  689.         {
  690.             msg_req("This screen is not deep enough\nto allow true-color rendering.\nPlease open the one with higher\ncolor depth (at least 15 bits).");
  691.             stop = TRUE;
  692.             return;
  693.         }
  694.  
  695.         if(KeyBase)
  696.             DitherLine(handle, (UBYTE *)buffer, len, x, y);
  697.         else
  698.             if(handle->wnd->WScreen->Width - 40 > 600 || handle->wnd->WScreen->Height + 51 > 563 || (count + 11 > 61))
  699.             {
  700.                 msg_req(registration_info);
  701.                 stop = TRUE;
  702.                 return;
  703.             }
  704.  
  705.         WritePixelArray(buffer, 0, 0, len * 4, handle->wnd->RPort, x, y, len, 1, RECTFMT_RGBA);
  706.     }
  707. }
  708.  
  709. void __asm __saveds R3DReadLine(register __a0 struct R3DHandle *handle,register __a1 int *buffer,register __a2 int len,register __d0 int x,register __d1 int y)
  710. {
  711.     if(handle->wnd && handle->depth >= 15)
  712.     {
  713.         if(handle->wnd->Flags & WFLG_GIMMEZEROZERO)
  714.             ReadPixelArray(buffer, 0, 0, len * 4, handle->wnd->RPort, x, y, len, 1, RECTFMT_RGBA);
  715.         else
  716.             ReadPixelArray(buffer, 0, 0, len * 4, handle->wnd->RPort, x + handle->wnd->BorderLeft, y + handle->wnd->BorderTop, len, 1, RECTFMT_RGBA);
  717.     }
  718. }
  719.  
  720. void __asm __saveds R3DClsScr(register __a0 struct R3DHandle *handle,register __a1 ULONG color)
  721. {
  722. }
  723.  
  724. int *__asm __saveds R3DCustomSave(register __a0 APTR handle,register __a1 char *name,register __a2 int x,register __d0 int y,register __d1 int w,register __d2 int h)
  725. {
  726.  return(NULL);
  727. }
  728.  
  729.  
  730. int __asm __saveds R3DInitRen(register __a0  struct R3DHandle *handle)
  731. {
  732.     return(TRUE);
  733. }
  734.  
  735. void __asm __saveds R3DEndRen(register __a0  struct R3DHandle *handle)
  736. {
  737. }
  738.  
  739. int __asm __saveds R3DEndRow(register __a0  struct R3DHandle *handle, register __a1 int y)
  740. {
  741.     if(stop)
  742.     {
  743.         stop = FALSE;
  744.         return(FALSE);
  745.     }
  746.  
  747.     return(TRUE);
  748. }
  749.  
  750. void __asm __saveds R3DGetAspect(
  751. register __a0  struct R3DHandle *handle,
  752. register __a1 int *w ,
  753. register __d0 int *h)
  754. {
  755.     *h = *w = 1;
  756. }
  757.  
  758. int __asm __saveds R3DExtF(register __a0  struct R3DHandle *handle)
  759. {
  760.     return(NULL);
  761. }
  762.  
  763.  
  764. int __saveds __UserLibInit(void)
  765. {
  766.     char *var;
  767.  
  768.     SysBase = (*(struct Library **)4);
  769.  
  770.     if(CyberGfxBase = OpenLibrary("cybergraphics.library", 40L))
  771.     {
  772.         if(!(KeyBase = (struct KeyBase *)OpenLibrary(KEY_NAME, 40L)))
  773.         {
  774.             if(var = AllocVec(KEYPATH_VAR_SIZE, MEMF_ANY))
  775.             {
  776.                 if(-1 != GetVar(KEYPATH_VAR_NAME, var, KEYPATH_VAR_SIZE, NULL))
  777.                 {
  778.                     if(AddPart(var, KEY_NAME, KEYPATH_VAR_SIZE))
  779.                         KeyBase = (struct KeyBase *)OpenLibrary(var, 40L);
  780.                 }
  781.                 FreeVec(var);
  782.             }
  783.         }
  784.  
  785.         NewList(&handle_list);
  786.         InitSemaphore(&sem);
  787.         stop = FALSE;
  788.  
  789.         return(0);
  790.     }
  791.  
  792.     return(1);
  793. }
  794.  
  795. void __saveds __UserLibCleanup(void)
  796. {
  797.     if(KeyBase)
  798.         CloseLibrary((struct Library *)KeyBase);
  799.  
  800.     if(CyberGfxBase)
  801.         CloseLibrary(CyberGfxBase);
  802. }
  803.